import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:v50art/Util.dart';
import 'package:v50art/service/CacheService.dart';

class NetworkService {
  static late String currentBaseUrl;
  static late Dio _dio;
  static setup({required String baseUrl}) async {
    if (!baseUrl.endsWith("/")) {
      currentBaseUrl = "$baseUrl/";
    } else {
      currentBaseUrl = baseUrl;
    }
    _dio = Dio();
  }

  static updateUrl({required String baseUrl}) async {
    if (!baseUrl.endsWith("/")) {
      currentBaseUrl = "$baseUrl/";
    } else {
      currentBaseUrl = baseUrl;
    }
  }

  static Future<ResponseData> post(
      {required String url, required Map<String, dynamic> map}) async {
    var token = await CacheService.getString("token");
    print('\x1B[94m |————————————————请求头部———————————————|\x1B[0m');
    print("token:$token");
    print('\x1B[94m |————————————————请求头部———————————————|\x1B[0m');
    print('\x1B[92m |————————————————请求参数———————————————|\x1B[0m');
    print('\x1B[92m POST:$currentBaseUrl$url\x1B[0m');
    print('\x1B[92m${json.encode(map)}\x1B[0m');
    print('\x1B[92m |————————————————请求参数———————————————|\x1B[0m');
    try {
      var res = (await _dio.post("$currentBaseUrl$url",
          data: map, options: Options(headers: {"token": token})));
      ResponseData response =
          _wrapperResponseHandler(ResponseData.fromJson(res.data));
      print(json.encode(res.data));
      return response;
    } catch (e) {
      if (e is RequestError) {
        rethrow;
      } else {
        Util.toast("网络错误");
        rethrow;
      }
    }
  }

  static ResponseData _wrapperResponseHandler(ResponseData responseData) {
    if (responseData.code != 2000) {
      throw RequestError(
          code: responseData.code!, message: responseData.message!);
    }
    return responseData;
  }
}

class RequestError {
  String message;
  int code;
  RequestError({required this.code, required this.message});
}

class ResponseData {
  final int? code;
  final String? message;
  final dynamic data;
  final int? count;
  ResponseData({this.code, this.message, this.data, this.count});
  ResponseData.fromJson(Map json)
      : code = toInt(json['code']),
        message = json['message'] as String?,
        data = json['data'],
        count = toInt(json['count']);
  T? getTypedData<T>(T? Function(Map? map) creator) {
    var map = data as Map<String, dynamic>?;
    if (map == null) {
      return null;
    }
    return creator(map);
  }

  List<T>? getTypedList<T>(T? Function(Map? map) creator) {
    List? list = data as List?;
    return toList(list, creator);
  }

  static List<T>? toList<T>(List? mapList, T? Function(Map? map) creator) {
    if (mapList == null) {
      return null;
    }
    List<T> ret = [];
    for (var m in mapList) {
      if (m == null) continue;
      var t = creator(m);
      if (t != null) {
        ret.add(t);
      }
    }
    return ret;
  }

  static int? toInt(dynamic data) {
    try {
      if (data == null) return null;
      if (data.runtimeType == int) return data;
      if (data.runtimeType == double) return (data as double).toInt();
      if (data.runtimeType == String) {
        String? string = (data as String?)?.trim();
        if (string == null || string.isEmpty) return null;
        return int.tryParse(string);
      }
    } catch (e, s) {
      print(e.toString());
      print(s.toString());
    }

    return null;
  }
}
